/*
 * ------------------------------------------------------------------
 * 密钥鉴权中间件
 * @说明：
 * 只有在服务中开启鉴权 且 开启的是鉴权方式是token，则会触发该中间件反之则跳过
 * 每次触发中间件都会向数据库查询token记录是否正常,是否过期等一系列环节
 * 并在验证成功后向 req对象中添加以下数据
 *
 * req.$user 本次token的用户id
 *
 * ------------------------------------------------------------------
 * @关于我：
 * QQ:2815473064
 * wechat:13531609457
 * ------------------------------------------------------------------
 */
// 密钥校验API
const SecretKeyVerify = require("../../api/token/verify");
const Redis = require("../../sql/redis");
const JWT = require("../../utils/jwt");

module.exports = async (req, res, next) => {
  try {
    let { way, status, skip, type } = req.$SecretKeyConfig;
    // 密钥鉴权是否开启
    if (!status) {
      next();
      return;
    }
    // 获取当前路径
    let currentPath = req.$pathname;
    // 是否跳过鉴权
    let ifSkip = skip.some((SkipPath) => {
      if (typeof SkipPath === 'string') {
        if (currentPath === SkipPath) {
          return true;
        }
      } else if (SkipPath instanceof RegExp) {
        if (SkipPath.test(currentPath)) {
          return true;
        }
      }
    })
    // 是否跳过当前路径
    if (ifSkip) {
      next();
      return;
    }
    //   获取请求方式
    if (way == "token") {
      //   token配置对象
      let tokenConfig = type.token;
      let { key, position } = tokenConfig;
      let token = null;
      if (!key) {
        throw { code: 500, msg: "鉴权错误,token未配置key值" };
      }
      if (position == "cookie") {
        token = req.cookie[key];
      } else {
        token = req.headers[key];
      }
      //   当前请求的token
      if (!token) {
        throw { statusCode: 403, msg: "请携带token" };
      }
      try {
        // 使用JWT解构出用户信息
        let { data } = JWT.verify(token);
        let { user, username, roles, super_admin } = data || {
          user: null,
          username: null,
          roles: null,
          super_admin: null,
        };
        if (!user || !username) {
          throw { statusCode: 403, msg: "token密钥错误 -a300" };
        }
        req.$username = username;
        req.$user = user;
        req.$token = token;
        req.$roles = roles;
        req.$super_admin = super_admin;
        next();
      } catch (error) {
        throw { statusCode: 403, msg: "操作失败,不合法的token" };
      }
    } else {
      throw { statusCode: 403, msg: "鉴权方式错误" };
    }
  } catch (error) {
    throw error;
  }
};
